open Functions

type element = {
	tagname    : string;
	attributes : attr list;
	children   : node list;
	comment    : string option;
}

and node = 
  | ElementNode of element
  | TextNode of string list

and attr = string * (string option)

type program = node list



let rec program_to_string xx = node_list_to_string "" xx

and node_list_to_string delim = function
  | [] -> ""
  | hd :: tl -> delim ^ (node_to_string delim hd) ^ (node_list_to_string delim tl)

and attr_list_to_string = function
  | [] -> ""
  | (name, None  ) :: tl -> " " ^ name ^ "=" ^ (q name) ^ (attr_list_to_string tl)
  | (name, Some x) :: tl -> " " ^ name ^ "=" ^ (q x)    ^ (attr_list_to_string tl)

and node_to_string delim = function
  | TextNode xx -> (join "" xx) ^ "\n"

  | ElementNode {tagname=name; attributes=attrs; children=[]; comment=comment} -> 
  		"<" ^ name ^ (attr_list_to_string attrs) ^ " />\n"

  | ElementNode {tagname=name; attributes=attrs; children=children; comment=comment} ->
  		"<" ^ name ^ (attr_list_to_string attrs) ^ ">\n" ^ 
  			(node_list_to_string (delim ^ "    ") children) ^ 
  				delim ^ "</" ^ name ^ ">\n" 
  		

let rec program_to_plain_string xx = node_list_to_plain_string xx


and node_list_to_plain_string = function
  | [] -> ""
  | hd :: tl -> (node_to_plain_string hd) ^ (node_list_to_plain_string tl)


and attr_list_to_plain_string = function
  | [] -> ""
  | (name, None  ) :: tl -> " " ^ name ^ "=" ^ (q name) ^ (attr_list_to_plain_string tl)
  | (name, Some x) :: tl -> " " ^ name ^ "=" ^ (q x)    ^ (attr_list_to_plain_string tl)


and node_to_plain_string = function
  | TextNode xx -> join " " xx

  | ElementNode {tagname=name; attributes=attrs; children=[]; comment=comment} -> 
  		"<" ^ name ^ (attr_list_to_plain_string attrs) ^ " />"

  | ElementNode {tagname=name; attributes=attrs; children=children; comment=comment} ->
  		"<" ^ name ^ (attr_list_to_plain_string attrs) ^ ">" ^ (node_list_to_plain_string children) ^ "</" ^ name ^ ">" 








